package com.vhall.component.service.room.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Preconditions;
import com.vhall.component.dao.account.AccountMapper;
import com.vhall.component.dao.anchors.AnchorManageMapper;
import com.vhall.component.dao.livecolumn.LiveColumnMapper;
import com.vhall.component.dao.pendant.PendantMapper;
import com.vhall.component.dao.rbac.AccountAdminMapper;
import com.vhall.component.dao.record.RecordMapper;
import com.vhall.component.dao.room.AnchorRoomRelationMapper;
import com.vhall.component.dao.room.InvestRefRelationMapper;
import com.vhall.component.dao.room.RoomConfigMapper;
import com.vhall.component.dao.room.RoomMapper;
import com.vhall.component.dao.tag.PageChannelMapper;
import com.vhall.component.entity.account.AccountEntity;
import com.vhall.component.entity.livecolumn.entity.LiveColumnEntity;
import com.vhall.component.entity.pendant.PendantEntity;
import com.vhall.component.entity.record.RecordEntity;
import com.vhall.component.entity.room.RoomConfig;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.entity.room.dto.SelectInvestRefDTO;
import com.vhall.component.entity.room.entity.AnchorRoomRelationEntity;
import com.vhall.component.entity.room.entity.InvestRefRelationEntity;
import com.vhall.component.entity.room.entity.RoomsEntity;
import com.vhall.component.entity.room.enums.*;
import com.vhall.component.entity.room.vo.CreateRoomVO;
import com.vhall.component.entity.room.vo.InvestRefResponseVO;
import com.vhall.component.entity.room.vo.RoomAdminGetInfoVO;
import com.vhall.component.entity.room.vo.RoomsEntityVO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.framework.common.utils.CollectionUtils;
import com.vhall.component.framework.common.utils.DateTimeUtils;
import com.vhall.component.plugin.common.constant.ConstStr;
import com.vhall.component.plugin.common.constant.HttpConstant;
import com.vhall.component.plugin.common.constant.PaasCommonConstant;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.enums.RoomConfigStatusEnum;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.Token;
import com.vhall.component.plugin.common.support.TokenThreadLocal;
import com.vhall.component.plugin.common.utils.DateUtils;
import com.vhall.component.plugin.core.service.GuoXinService;
import com.vhall.component.plugin.core.service.PaasService;
import com.vhall.component.service.account.BaseUserPermissionService;
import com.vhall.component.service.common.BaseCommonService;
import com.vhall.component.service.room.RoomInnerService;
import com.vhall.component.service.room.utils.RoomUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author shimingming
 * @since 2023/4/27 19:53
 */
@Slf4j
public class RoomBaseService extends BaseUserPermissionService {


    @Value("${paas.web-domain}")
    public String webDomain;

    /**
     * 是否开启房间审核
     * 1为开启
     * 0为关闭房间审核
     */
    @Value("${project.room.audit:0}")
    public Integer roomAuditWitch;

    @Resource
    public RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public RoomMapper roomMapper;

    @Autowired
    public PaasService paasService;

    @Resource
    public PageChannelMapper pageChannelMapper;

    @Resource
    public AnchorManageMapper anchorManageMapper;

    @Resource
    public PendantMapper pendantMapper;

    @Autowired
    public AccountAdminMapper accountAdminMapper;

    public final DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Autowired
    public RoomInnerService roomInnerService;

    @Autowired
    public RecordMapper recordMapper;

    @Autowired
    public RoomConfigMapper roomConfigMapper;

    @Resource
    public LiveColumnMapper liveColumnMapper;

    @Resource
    public InvestRefRelationMapper investRefRelationMapper;

    @Resource
    public AnchorRoomRelationMapper anchorRoomRelationMapper;
    @Resource
    public AccountMapper accountMapper;
    @Resource
    public GuoXinService guoXinService;

    @Value("${guoxin.column.default_name:''}")
    private String defaultName;

    @Resource
    private BaseCommonService baseCommonService;

    /**
     * 房间关联产品最大维护数量上限
     */
    public static final int ROOM_PROD_MAX_LIMIT = 100;
    /**
     * 单个产品编号限制长度上限
     */
    private static final int ROOM_PROD_LENGTH_LIMIT = 64;
    /**
     * 录播视频加入缓存，给定时调度使用
     * <p>
     * auditStatus 审核状态: 0|待审核,-1|审核驳回,1|审核通过,-2|审核封禁
     */
    public void addRecordedVideoToCache(RoomsEntity room, int auditStatus) {

        if (Objects.equals(room.getStatus(),RoomStatusEnum.TO_BE_BROADCAST.getStatus()) && room.getLiveType().equals(LiveRoomTypeEnum.FAKE_LIVE_BROADCAST.getType())) {

            // 过期时间等于当前房间的开播时间+1s ，距离当前的时间
            LocalDateTime nowTime = LocalDateTime.now();
            LocalDateTime startTime = room.getStartTime();

            long betweenTwoTime = DateTimeUtils.betweenTwoTime(nowTime, startTime, ChronoUnit.SECONDS);

            String listKey = RedisKey.RECORDED_VIDEO_LIST;
            String singleKey = RedisKey.RECORDED_VIDEO_SINGLE + room.getIlId();
            redisTemplate.opsForSet().add(listKey, room.getIlId());
            redisTemplate.opsForValue().set(singleKey, auditStatus, betweenTwoTime + 1, TimeUnit.SECONDS);

            log.info(MessageFormat.format("房间号：【{0}】,开播时间：【{1}】，当前时间：【{2}】，两者相距：【{3}】秒，状态：【{4}】"
                    , room.getIlId()
                    , DateUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN)
                    , DateUtil.format(nowTime, DatePattern.NORM_DATETIME_PATTERN)
                    , betweenTwoTime + 1
                    , auditStatus
            ));

        }
    }
    /**
     * 录播视频加入缓存，给定时调度使用
     * <p>
     * auditStatus 审核状态: 0|待审核,-1|审核驳回,1|审核通过,-2|审核封禁
     */
    public void addRecordedVideoToCache(RoomsEntityDTO room, int auditStatus) {

        if (room.getLiveType().equals(LiveRoomTypeEnum.FAKE_LIVE_BROADCAST.getType())) {

            // 过期时间等于当前房间的开播时间+1s ，距离当前的时间
            LocalDateTime nowTime = LocalDateTime.now();
            LocalDateTime startTime = room.getStartTime();

            long betweenTwoTime = DateTimeUtils.betweenTwoTime(nowTime, startTime, ChronoUnit.SECONDS);
            if (betweenTwoTime<=0) {
                betweenTwoTime = 5 * 60;
            }
            String listKey = RedisKey.RECORDED_VIDEO_LIST;
            String singleKey = RedisKey.RECORDED_VIDEO_SINGLE + room.getIlId();
            redisTemplate.opsForSet().add(listKey, room.getIlId());
            redisTemplate.opsForValue().set(singleKey, auditStatus, betweenTwoTime + 1, TimeUnit.SECONDS);

            log.info(MessageFormat.format("房间号：【{0}】,开播时间：【{1}】，当前时间：【{2}】，两者相距：【{3}】秒，状态：【{4}】"
                    , room.getIlId()
                    , DateUtil.format(startTime, DatePattern.NORM_DATETIME_PATTERN)
                    , DateUtil.format(nowTime, DatePattern.NORM_DATETIME_PATTERN)
                    , betweenTwoTime + 1
                    , auditStatus
            ));

        }
    }

    /**
     * 基础信息校验
     */
    public void basicValidateVo(CreateRoomVO reqVO) {

        switch (Objects.requireNonNull(LiveRoomTypeEnum.parse(reqVO.getLiveType()))) {
            case LIVE_BROADCAST:
                Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getBeginTime()), "直播开始时间不能为空！");

                if (StringUtils.isNotBlank(reqVO.getRoomId())
                        && getRoomsEntity(reqVO.getRoomId()).getStatus().equals(RoomStatusEnum.END_BROADCAST.getStatus())) {
                    // 编辑，审核时候，并且当前房间已经结束，不校验时间

                } else {
                    if (LocalDateTimeUtil.parse(reqVO.getBeginTime(), DatePattern.NORM_DATETIME_PATTERN).isBefore(LocalDateTime.now())) {
                        throw new BusinessException(BizErrorCode.BIZ_OPEN_TIME_ERROR);
                    }
                }

                break;
            case FAKE_LIVE_BROADCAST:
                Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getDemandVodId()), "视频不能为空！");

                Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getBeginTime()), "直播开始时间不能为空！");
                if (StringUtils.isBlank(reqVO.getRoomId())) {
                    // 创建房间的时候，录播模式校验时间
                    if (LocalDateTimeUtil.parse(reqVO.getBeginTime(), DatePattern.NORM_DATETIME_PATTERN).isBefore(LocalDateTime.now())) {
                        throw new BusinessException(BizErrorCode.BIZ_OPEN_TIME_ERROR);
                    }
                } else {
                    // 编辑、审核
                    RoomsEntity room = getRoomsEntity(reqVO.getRoomId());
                    if (room.getStatus().equals(RoomStatusEnum.END_BROADCAST.getStatus())) {
                        // 结束状态，不校验时间
                    } else if (room.getStatus().equals(RoomStatusEnum.LIVE_BROADCAST.getStatus())) {
                        // 直播中，不允许编辑
                        throw new BusinessException(BizErrorCode.COMP_COUPON_LIVING_NOT_EDIT);
                    } else if (room.getStatus().equals(RoomStatusEnum.TO_BE_BROADCAST.getStatus())) {
                        // 待直播，时间校验
                        if (LocalDateTimeUtil.parse(reqVO.getBeginTime(), DatePattern.NORM_DATETIME_PATTERN).isBefore(LocalDateTime.now())) {
                            throw new BusinessException(BizErrorCode.BIZ_OPEN_TIME_ERROR);
                        }
                    }
                }

                break;
            case ON_DEMAND:
                Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getDemandVodId()), "视频不能为空！");
                break;
            default:
                break;
        }



        if (reqVO.getPendantId() != null) {
            PendantEntity pendantEntity = pendantMapper.selectById(reqVO.getPendantId());
            Preconditions.checkArgument(pendantEntity != null, "挂件不存在！");
        }
//        暖场类型为暖场视频时的判定
        if (Objects.equals(RoomsWarmTypeEnum.VIDEO.getValue(),reqVO.getWarmType())) {
            if (StrUtil.isBlank(reqVO.getWarmVodId())) {
                throw new BusinessException(BizErrorCode.BIZ_ROOM_WARM_VOID_EMPTY);
            }
        }
//        适当性校验豁免设置校验
        if(!Objects.equals(LiveContentTypeEnum.TYPE_1.getValue(),reqVO.getLiveContentType())){
            List<String> exemptProdCodes = reqVO.getExemptProdCodes();
            if (CollUtil.isNotEmpty(exemptProdCodes)) {
                if (exemptProdCodes.size()>= ROOM_PROD_MAX_LIMIT) {
                    throw new BusinessException(BizErrorCode.BIZ_ROOM_EXEMPT_PROD_MAX_LIMIT);
                }
                if(exemptProdCodes.stream().filter(data -> StrUtil.isNotBlank(data) && data.length() >= ROOM_PROD_LENGTH_LIMIT).count()>=1){
                    throw new BusinessException(BizErrorCode.BIZ_ROOM_RELATION_PROD_LENGTH_LIMIT);
                }
            }
        }
//        可用户观看范围相关基础校验
//        国信观看用户范围类型
        Integer limitUserScope = reqVO.getLimitUserScope();
        if (Objects.equals(LiveLimitUserScopeEnum.HOLDING_PRODUCT_USER_VISIBLE.getValue(), limitUserScope)) {
            List<String> visibleProdCodes = reqVO.getVisibleProdCodes();
            if (CollUtil.isEmpty(visibleProdCodes)) {
                throw new BusinessException(BizErrorCode.BIZ_ROOM_LIMIT_USER_SCOPE_PROD_EMPTY);
            }else{
                if (visibleProdCodes.size()>= ROOM_PROD_MAX_LIMIT) {
                    throw new BusinessException(BizErrorCode.BIZ_ROOM_LIMIT_USER_SCOPE_PROD_MAX_LIMIT);
                }
                if(visibleProdCodes.stream().filter(data -> StrUtil.isNotBlank(data) && data.length() >= ROOM_PROD_LENGTH_LIMIT).count()>=1){
                    throw new BusinessException(BizErrorCode.BIZ_ROOM_RELATION_PROD_LENGTH_LIMIT);
                }
            }
        }else if(Objects.equals(LiveLimitUserScopeEnum.WHITELIST_USER_VISIBLE.getValue(), limitUserScope)){
            Integer whiteFileId = reqVO.getWhiteFileId();
            if (Objects.isNull(whiteFileId)) {
                throw new BusinessException(BizErrorCode.BIZ_ROOM_RELATION_WHITE_FILE_EMPTY);
            }
        }
    }


    /**
     * 获取审核人姓名
     */
    public String assemblyReviewer(RoomsEntity room) {
        Integer reviewer = room.getReviewer();
        String reviewerName = "";
        if (reviewer != null && reviewer != 0) {
            AccountEntity accountEntity = accountMapper.selectById(reviewer);
            reviewerName = accountEntity.getNickname();
        }
        return reviewerName;
    }


    /**
     * 查询 直播时长
     */
    public String findLiveTime(RoomsEntity room) {
        String liveTime = "";

        switch (Objects.requireNonNull(RoomStatusEnum.parse(room.getStatus()))) {
            case TO_BE_BROADCAST:
                Integer demondVodLiveTime = getDemondVodLiveTime(room);
                liveTime = demondVodLiveTime != null ? DateUtils.toSeconds(demondVodLiveTime) : ConstStr.TIME_ZERO;
                break;
            case LIVE_BROADCAST:
                liveTime = buildStartRoomsEntityVO(room);
                break;
            case END_BROADCAST:
                liveTime = buildStopRoomsEntityVO(room);
                break;
            default:
                break;
        }

        return liveTime;
    }

    private String buildStopRoomsEntityVO(RoomsEntity room) {
        String liveTime = ConstStr.TIME_ZERO;
        if (room.getBeginLiveTime() != null && room.getEndLiveTime() != null) {
            Duration dur = Duration.between(room.getBeginLiveTime(), room.getEndLiveTime());
            int seconds = (int) dur.getSeconds();
            liveTime = seconds < 0 ? ConstStr.TIME_ZERO : DateUtils.toSeconds(seconds);
        }
        return liveTime;
    }

    private String buildStartRoomsEntityVO(RoomsEntity room) {

        Integer demondVodLiveTime = getDemondVodLiveTime(room);
        if (demondVodLiveTime != null) {
            return DateUtils.toSeconds(demondVodLiveTime);
        }

        String liveTime = ConstStr.TIME_ZERO;

        JSONObject result = paasService.getStreamStatus(room.getRoomId());
        if (result.getInteger(HttpConstant.CODE) != HttpConstant.SUCCESS_CODE) {
            log.error("拉取paas流状态列表错误");
        } else {
            JSONObject data = result.getJSONObject(HttpConstant.DATA);
            JSONObject obj = data.getJSONObject(room.getRoomId());
            String pushTime = obj.getString("push_time");
            String endTime = obj.getString("end_time");

            if (obj.getInteger(PaasCommonConstant.STREAM_STATUS) == com.vhall.component.plugin.common.constant.RoomConstant.STATUS_START) {
                if (room.getBeginLiveTime() != null) {
                    Duration dur = Duration.between(LocalDateTime.parse(pushTime, df), LocalDateTime.now());
                    int seconds = (int) dur.getSeconds();
                    liveTime = DateUtils.toSeconds(seconds);
                }
            } else {
                int seconds = 0;
                // 直播结束
                if (!endTime.equals(ConstStr.DATE_TIME_ZERO) && pushTime.equals(ConstStr.DATE_TIME_ZERO)) {
                    Duration dur = Duration.between(LocalDateTime.parse(endTime, df), LocalDateTime.parse(pushTime, df));
                    seconds = (int) dur.getSeconds();
                }
                liveTime = DateUtils.toSeconds(seconds);

            }
        }
        return liveTime;
    }

    /**
     * 获取当前房间对应的回放 时长
     */
    private Integer getDemondVodLiveTime(RoomsEntity room) {
        String recordId = room.getRecordId();
        if (room.getLiveType().equals(LiveRoomTypeEnum.ON_DEMAND.getType())
                && StringUtils.isNotBlank(recordId)) {

            LambdaQueryWrapper<RecordEntity> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(RecordEntity::getVodId, recordId);
            List<RecordEntity> recordEntities = recordMapper.selectList(queryWrapper);

            if (CollectionUtils.isNotEmpty(recordEntities)) {
                RecordEntity recordEntity = recordEntities.get(0);
                return recordEntity.getDuration();
            }
        }

        return null;
    }

    public RoomsEntity getRoomsEntity(String roomId) {
        LambdaQueryWrapper<RoomsEntity> where = Wrappers.lambdaQuery();
        where.eq(RoomsEntity::getRoomId, roomId);
        where.eq(StringUtils.isNotBlank(getUserPermission()), RoomsEntity::getOrgCode, getUserPermission());
        RoomsEntity room = roomMapper.selectOne(where);
        if (room == null) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        baseCommonService.convertUrl(room, "coverImage", "image", "posterUrl");
        return room;
    }

    public RoomsEntity getRoomsEntityByIlId(RoomAdminGetInfoVO reqVO) {
        LambdaQueryWrapper<RoomsEntity> where = Wrappers.lambdaQuery();
        where.eq(RoomsEntity::getIlId, reqVO.getIlId());
        where.eq(reqVO.getLiveType() != null, RoomsEntity::getLiveType, reqVO.getLiveType());
        return roomMapper.selectOne(where);
    }

    /**
     * 直播中，禁止编辑
     */
    public RoomsEntity prohibitEditing(String roomId) {

        RoomsEntity room = getRoomsEntity(roomId);

        if (room.getStatus().equals(RoomStatusEnum.LIVE_BROADCAST.getStatus())) {
            throw new BusinessException(BizErrorCode.COMP_COUPON_LIVING_NOT_EDIT);
        }
        return room;
    }

    /**
     * 把查询到的 RoomsEntity 分页对象转成 list 集合包装的 RoomsEntityVO对象
     */
    public List<RoomsEntityVO> roomsEntityToListVo(Page<RoomsEntity> page) {
        List<RoomsEntity> records = page.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new ArrayList<>();
        }

        List<RoomsEntityVO> rooms = new ArrayList<>();

        // 获取当前房间配置信息
        Map<String, List<RoomConfig>> roomConfigMap = getRoomConfigListMap(records);

        // 获取栏目信息
        Map<Integer, String> columnMap = getColumnStringMap(records);

        // 投资依据信息
        Map<Integer, List<InvestRefResponseVO>> investMap = getInvestInfo(records);

        // 获取主播名称
        Map<Integer, AnchorRoomRelationEntity> userNameMap = getUserName(records);

        for (RoomsEntity room : records) {
            baseCommonService.convertUrl(room, "coverImage", "image", "posterUrl");
            rooms.add(convertToRoomsEntityVO(room, roomConfigMap, columnMap, investMap, userNameMap));
        }


        return rooms;
    }

    /**
     * 获取主播名称
     */
    public Map<Integer, AnchorRoomRelationEntity> getUserName(List<RoomsEntity> records) {
        List<AnchorRoomRelationEntity> relationEntities = anchorRoomRelationMapper.selectInfoList(records.stream().map(RoomsEntity::getIlId).collect(Collectors.toList()));
        Map<Integer, AnchorRoomRelationEntity> stringMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(relationEntities)) {
            stringMap = relationEntities.stream().collect(Collectors.toMap(AnchorRoomRelationEntity::getIlId, e -> e));
        }
        return stringMap;
    }

    public Map<String, List<RoomConfig>> getRoomConfigListMap(List<RoomsEntity> records) {
        LambdaQueryWrapper<RoomConfig> where = Wrappers.lambdaQuery();
        where.in(RoomConfig::getRoomId, records.stream().map(RoomsEntity::getRoomId).collect(Collectors.toList()));
        List<RoomConfig> roomConfigs = roomConfigMapper.selectList(where);
        if (CollectionUtils.isNotEmpty(roomConfigs)) {
            return roomConfigs.stream().collect(Collectors.groupingBy(RoomConfig::getRoomId));
        }
        return new HashMap<>();
    }

    /**
     * 获取栏目信息
     */
    public Map<Integer, String> getColumnStringMap(List<RoomsEntity> records) {
        LambdaQueryWrapper<LiveColumnEntity> where2 = Wrappers.lambdaQuery();
        where2.in(LiveColumnEntity::getId, records.stream().map(RoomsEntity::getColumnId).collect(Collectors.toList()));
        List<LiveColumnEntity> columnEntityList = liveColumnMapper.selectList(where2);
        if (CollectionUtils.isNotEmpty(columnEntityList)) {
            return columnEntityList.stream().collect(Collectors.toMap(LiveColumnEntity::getId, LiveColumnEntity::getName));
        }
        return new HashMap<>();
    }

    /**
     * 投资依据信息
     * <p>
     * return Map<Integer, List<InvestRefEntity>> key 是 ilid list 是 invest_ref 表里面的数据
     */
    public Map<Integer, List<InvestRefResponseVO>> getInvestInfo(List<RoomsEntity> records) {
        List<Integer> ilidList = records.stream().map(RoomsEntity::getIlId).collect(Collectors.toList());
        LambdaQueryWrapper<InvestRefRelationEntity> investRefRelationWrapper = Wrappers.lambdaQuery();
        investRefRelationWrapper.in(InvestRefRelationEntity::getIlId,ilidList);
        List<InvestRefRelationEntity> investRefRelationEntities = investRefRelationMapper.selectList(investRefRelationWrapper);

        Map<Integer, List<InvestRefResponseVO>> result = new HashMap<>();
        if (CollectionUtils.isNotEmpty(investRefRelationEntities)) {
            Map<Integer, List<InvestRefRelationEntity>> listMap = investRefRelationEntities.stream().collect(Collectors.groupingBy(InvestRefRelationEntity::getIlId));
            List<Integer> investRefIds = investRefRelationEntities.stream().map(InvestRefRelationEntity::getInvestRefId).distinct().collect(Collectors.toList());
            Map<Integer, InvestRefResponseVO> investRefEntityMap = new HashMap<>();
            Token token = Optional.ofNullable(TokenThreadLocal.getToken()).orElseThrow(()->new BusinessException(BizErrorCode.AUTH_LOGIN_TOKEN_INVALID));
            SelectInvestRefDTO dto = new SelectInvestRefDTO();
            dto.setNotesid(token.getThirdPartyUserId());
            dto.setOrgCode(token.getOrgCode());
            for (Integer investRefId : investRefIds) {
                dto.setJyid(Objects.toString(investRefId));
                try{
                    InvestRefResponseVO entity = guoXinService.getInvestRefEntity(dto, investRefId);
                    investRefEntityMap.put(investRefId,entity);
                }catch (Exception e){
                    log.error("远程获取投资依据发生报错",e);
                }
            }
            for (Map.Entry<Integer, List<InvestRefRelationEntity>> listEntry : listMap.entrySet()) {
                Integer ilid = listEntry.getKey();
                List<InvestRefRelationEntity> listEntryValue = listEntry.getValue();
                List<InvestRefResponseVO> list = new ArrayList<>();
                for (InvestRefRelationEntity investRefRelationEntity : listEntryValue) {
                    list.add(investRefEntityMap.get(investRefRelationEntity.getInvestRefId()));
                }
                result.put(ilid, list);


            }
        }
        return result;
    }

    /**
     * 数据类型转换
     */
    private RoomsEntityVO convertToRoomsEntityVO(RoomsEntity room
            , Map<String, List<RoomConfig>> roomConfigMap
            , Map<Integer, String> columnMap
            , Map<Integer, List<InvestRefResponseVO>> investMap
            , Map<Integer, AnchorRoomRelationEntity> userNameMap) {

        RoomsEntityVO vo = new RoomsEntityVO();
        BeanUtils.copyProperties(room, vo);

        vo.setName(room.getSubject());
        vo.setImage(room.getCoverImage());
        //查询 直播时长
        vo.setLiveTime(findLiveTime(room));

        vo.setStatusStr(RoomUtils.getRoomStatusStr(room.getAuditStatus(), room.getStatus(), roomAuditWitch));


        if (CollectionUtils.isNotEmpty(roomConfigMap) && CollectionUtils.isNotEmpty(roomConfigMap.get(room.getRoomId()))) {
            List<RoomConfig> roomConfigs = roomConfigMap.get(room.getRoomId());
            Map<String, Integer> integerMap = roomConfigs.stream().collect(Collectors.toMap(RoomConfig::getConfigKey, RoomConfig::getConfigValue, (e1, e2) -> e1));

            vo.setReservationStatus(integerMap.get(RoomConfigStatusEnum.RESERVATION_STATUS.getValue()));
            vo.setCommentStatus(integerMap.get(RoomConfigStatusEnum.COMMENT_STATUS.getValue()));
            vo.setChatManagementLiveStatus(integerMap.get(RoomConfigStatusEnum.CHAT_MANAGEMENT_LIVE.getValue()));
            vo.setChatManagementPlaybackStatus(integerMap.get(RoomConfigStatusEnum.CHAT_MANAGEMENT_PLAYBACK.getValue()));
            vo.setGiftLiveStatus(integerMap.get(RoomConfigStatusEnum.CHAT_MANAGEMENT_GIFT.getValue()));
        }


        vo.setColumnName(columnMap.isEmpty() || room.getColumnId() == null || room.getColumnId() == 0 || !columnMap.containsKey(room.getColumnId()) ? defaultName : columnMap.get(room.getColumnId()));
        vo.setLiveContentTypeName(LiveContentTypeEnum.getDescription(vo.getLiveContentType()));
        vo.setAuditStatusName(RoomAuditStatusEnum.getDescription(vo.getAuditStatus()));

        Boolean investRefListFlag=false;
        if (!investMap.isEmpty()) {
            List<InvestRefResponseVO> investRefEntities = investMap.get(room.getIlId());
            if (CollectionUtils.isNotEmpty(investRefEntities)) {
                investRefListFlag=true;
            }
        }
        vo.setInvestRefListFlag(investRefListFlag);
        vo.setUserName(userNameMap.isEmpty() || userNameMap.get(room.getIlId()) == null ? "" : userNameMap.get(room.getIlId()).getUserName());

        // 备注展示逻辑
        //1.主播审核驳回后，直播管理列表展示驳回，并且展示驳回的备注
        //2.主播审核通过 平台未审核，直播管理列表展示待审核状态，展示主播审核通过填的备注
        // 3.主播审核通过 合规审核通过，直播管理列表展示审核通过状态，展示合规审核通过填的备注
        // 4.主播审核通过 合规审核驳回，直播管理列表展示审核驳回状态，展示合规审核驳回填的备注
        Integer playbackStatusFinal = room.getPlaybackStatus();
        String playbackNoteFinal = room.getPlaybackNote();
        if (room.getLiveContentType().equals(LiveContentTypeEnum.TYPE_3.getValue())
                && playbackStatusFinal.equals(RoomAuditStatusEnum.APPROVED.getAuditStatus())) {
            playbackStatusFinal = room.getPlaybackStatusSecond();
            if (!room.getPlaybackStatusSecond().equals(RoomAuditStatusEnum.CHECK_PENDING.getAuditStatus())) {
                playbackNoteFinal = room.getPlaybackNoteSecond();
            }
        }
        vo.setPlaybackStatusFinal(playbackStatusFinal);
        vo.setPlaybackNoteFinal(playbackNoteFinal);
        return vo;
    }

    /**
     * 12个月
     * 时间校验
     */
    public void validateSixTime(String startTime,String endTime) {
        LocalDateTime start = DateUtil.parseLocalDateTime(startTime, DatePattern.NORM_DATE_PATTERN);
        LocalDateTime end = DateUtil.parseLocalDateTime(endTime, DatePattern.NORM_DATE_PATTERN);

        long between = DateTimeUtils.betweenTwoTime(start, end, ChronoUnit.MONTHS);
        if (between > 12) {
            throw new BusinessException(BizErrorCode.BIZ_DATA_OVER_LONG_ERROR);
        }
    }


}
